package com.jjzhk.common.client;

import com.jjzhk.common.bean.RpcRequest;
import com.jjzhk.common.bean.RpcResponse;
import com.jjzhk.common.handler.RpcClientHandler;
import com.jjzhk.common.handler.RpcDecoder;
import com.jjzhk.common.handler.RpcEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Proxy;
import java.util.UUID;

/**
 * RpcClient
 *
 * @author : JJZHK
 * @date : 2016-08-14
 * @comments :
 **/
public class RpcClient{
    private Logger logger = LoggerFactory.getLogger(RpcClient.class);
    private String address;
    private int port;
    private Class<?> interfaceClass;
    private String version;

    private RpcResponse response;

    public RpcClient(String address, int port, Class<?> interfaceClass, String version) {
        this.address = address;
        this.port = port;
        this.interfaceClass = interfaceClass;
        this.version = version;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public <T> T Create()
    {
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass},
                (proxy, method, args) -> {
                    RpcRequest request = new RpcRequest();
                    request.setRequestID(UUID.randomUUID().toString());
                    request.setInterfaceName(method.getDeclaringClass().getName());
                    request.setServiceVersion(version);
                    request.setMethodName(method.getName());
                    request.setParameterTypes(method.getParameterTypes());
                    request.setParameterValues(args);

                    long time = System.currentTimeMillis();
                    RpcResponse response = new RpcClientHandler(address,port).send(request);
                    logger.info("time: {}ms", System.currentTimeMillis() - time);
                    if (response == null) {
                        throw new RuntimeException("response is null");
                    }
                    // 返回 RPC 响应结果
                    if (response.hasException()) {
                        throw response.getException();
                    } else {
                        return response.getResult();
                    }
                });
    }




}
